"""
日志管理模块

提供统一的日志管理功能，支持分级日志记录、日志文件轮转和彩色日志输出。
"""

import os
import sys
import logging
import logging.handlers
from pathlib import Path
from typing import Optional
import colorlog

from .config import get_config, set_config


class LoggerManager:
    """日志管理器类"""
    
    def __init__(self, name: str = "epidemic_dashboard"):
        """
        初始化日志管理器
        
        Args:
            name: 日志器名称
        """
        self.name = name
        self.logger = logging.getLogger(name)
        self._setup_logger()
    
    def _setup_logger(self) -> None:
        """设置日志器"""
        # 清除现有的处理器
        self.logger.handlers.clear()
        
        # 设置日志级别
        log_level = get_config('logging.level', 'INFO')
        self.logger.setLevel(getattr(logging, log_level.upper()))
        
        # 创建格式化器
        formatter = self._create_formatter()
        
        # 添加控制台处理器
        console_handler = self._create_console_handler(formatter)
        self.logger.addHandler(console_handler)
        
        # 添加文件处理器
        file_handler = self._create_file_handler(formatter)
        if file_handler:
            self.logger.addHandler(file_handler)
        
        # 设置不传播到根日志器
        self.logger.propagate = False
    
    def _create_formatter(self) -> tuple[colorlog.ColoredFormatter, logging.Formatter]:
        """创建日志格式化器"""
        # 彩色日志格式
        color_formatter = colorlog.ColoredFormatter(
            fmt='%(log_color)s%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
            log_colors={
                'DEBUG': 'cyan',
                'INFO': 'green',
                'WARNING': 'yellow',
                'ERROR': 'red',
                'CRITICAL': 'red,bg_white',
            }
        )
        
        # 普通日志格式
        plain_formatter = logging.Formatter(
            fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        
        return color_formatter, plain_formatter
    
    def _create_console_handler(self, formatters) -> logging.StreamHandler:
        """创建控制台处理器"""
        color_formatter, plain_formatter = formatters
        
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setLevel(logging.DEBUG)
        
        # 在支持颜色的终端使用彩色格式
        if hasattr(sys.stdout, 'isatty') and sys.stdout.isatty():
            console_handler.setFormatter(color_formatter)
        else:
            console_handler.setFormatter(plain_formatter)
        
        return console_handler
    
    def _create_file_handler(self, formatters) -> Optional[logging.handlers.RotatingFileHandler]:
        """创建文件处理器"""
        color_formatter, plain_formatter = formatters
        
        log_file = get_config('logging.file', 'logs/app.log')
        log_path = Path(log_file)
        
        # 确保日志目录存在
        log_path.parent.mkdir(parents=True, exist_ok=True)
        
        try:
            # 获取日志文件大小限制
            max_size = get_config('logging.max_size', 10 * 1024 * 1024)  # 10MB
            backup_count = get_config('logging.backup_count', 5)
            
            file_handler = logging.handlers.RotatingFileHandler(
                log_path,
                maxBytes=max_size,
                backupCount=backup_count,
                encoding='utf-8'
            )
            
            file_handler.setLevel(logging.DEBUG)
            file_handler.setFormatter(plain_formatter)
            
            return file_handler
            
        except Exception as e:
            print(f"创建文件日志处理器失败: {e}")
            return None
    
    def get_logger(self) -> logging.Logger:
        """获取日志器"""
        return self.logger
    
    def set_level(self, level: str) -> None:
        """
        设置日志级别
        
        Args:
            level: 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
        """
        self.logger.setLevel(getattr(logging, level.upper()))
    
    def add_handler(self, handler: logging.Handler) -> None:
        """
        添加日志处理器
        
        Args:
            handler: 日志处理器
        """
        self.logger.addHandler(handler)
    
    def remove_handler(self, handler: logging.Handler) -> None:
        """
        移除日志处理器
        
        Args:
            handler: 日志处理器
        """
        self.logger.removeHandler(handler)


# 全局日志管理器实例
logger_manager = LoggerManager()


def get_logger(name: Optional[str] = None) -> logging.Logger:
    """
    获取日志器的便捷函数
    
    Args:
        name: 日志器名称，默认为epidemic_dashboard
        
    Returns:
        日志器实例
    """
    if name is None:
        return logger_manager.get_logger()
    else:
        return LoggerManager(name).get_logger()


def setup_logging(level: str = "INFO", log_file: Optional[str] = None) -> None:
    """
    设置日志系统的便捷函数
    
    Args:
        level: 日志级别
        log_file: 日志文件路径
    """
    global logger_manager
    
    if log_file:
        set_config('logging.file', log_file)
    
    set_config('logging.level', level)
    logger_manager = LoggerManager()
    
    logger = get_logger()
    logger.info(f"日志系统已初始化，级别: {level}")


def log_function_call(func):
    """
    函数调用日志装饰器
    
    Args:
        func: 被装饰的函数
        
    Returns:
        装饰后的函数
    """
    def wrapper(*args, **kwargs):
        logger = get_logger()
        logger.debug(f"调用函数: {func.__name__}")
        try:
            result = func(*args, **kwargs)
            logger.debug(f"函数 {func.__name__} 执行成功")
            return result
        except Exception as e:
            logger.error(f"函数 {func.__name__} 执行失败: {e}")
            raise
    return wrapper


def log_execution_time(func):
    """
    执行时间日志装饰器
    
    Args:
        func: 被装饰的函数
        
    Returns:
        装饰后的函数
    """
    import time
    
    def wrapper(*args, **kwargs):
        logger = get_logger()
        start_time = time.time()
        logger.debug(f"开始执行函数: {func.__name__}")
        
        try:
            result = func(*args, **kwargs)
            end_time = time.time()
            execution_time = end_time - start_time
            logger.info(f"函数 {func.__name__} 执行完成，耗时: {execution_time:.2f}秒")
            return result
        except Exception as e:
            end_time = time.time()
            execution_time = end_time - start_time
            logger.error(f"函数 {func.__name__} 执行失败，耗时: {execution_time:.2f}秒，错误: {e}")
            raise
    return wrapper


# 常用的日志函数
def debug(message: str) -> None:
    """记录调试信息"""
    get_logger().debug(message)


def info(message: str) -> None:
    """记录信息"""
    get_logger().info(message)


def warning(message: str) -> None:
    """记录警告信息"""
    get_logger().warning(message)


def error(message: str) -> None:
    """记录错误信息"""
    get_logger().error(message)


def critical(message: str) -> None:
    """记录严重错误信息"""
    get_logger().critical(message)


def exception(message: str) -> None:
    """记录异常信息"""
    get_logger().exception(message) 